using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;

namespace TestCases.Utils
{
    public static class CollectionsUtils
    {
        public static void AddAll<T>(this ICollection<T> target, IEnumerable<T> values)
        {
            foreach (var value in values)
            {
                target.Add(value);
            }
        }
        
        public static void AddAll<T>(this ICollection<T> target, IEnumerable values)
        {
            foreach (var value in values)
            {
                target.Add((T)value);
            }
        }

        public static IEnumerable Merge(this IEnumerable first, IEnumerable second, IEqualityComparer<object> comparer)
        {
            var result = new HashSet<object>(comparer);
            AddAll(result, first);
            AddAll(result, second);
            return result;
        }

        public static IEnumerable Merge(this IEnumerable first, IEnumerable second)
        {
            var result = new HashSet<object>();
            AddAll(result, first);
            AddAll(result, second);
            return result;
        }
        
                        
        public static IEnumerable<T> Merge<T>(this IEnumerable<T> first, IEnumerable<T> second)
        {
            var result = new HashSet<T>(first);
            result.UnionWith(second);
            return result;
        }
        
        public static IEnumerable<T> Merge<T>(this IEnumerable<T> first, IEnumerable<T> second, IEqualityComparer<T> comparer)
        {
            var result = new HashSet<T>(first, comparer);
            result.UnionWith(second);
            return result;
        }  
            
        public static int CalculateHash<T>(this HashSet<T> coll)
        {
            int count = 0;
            int hashCode = 0;
            foreach (var item in coll)
            {
                hashCode ^= item.GetHashCode();
                count++;
            }
            return hashCode ^ count;
        }
                
    }
}